package kassiopeia.agent;

import javax.annotation.PostConstruct;
import kassiopeia.agent.alerting.Alerting;
import kassiopeia.agent.seda.SEDA;
import kassiopeia.commons.AgentStatus;
import kassiopeia.commons.TaskSummary;
import kassiopeia.commons.exception.SedaException;
import kassiopeia.commons.model.task.TaskDescriptor;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.stereotype.Component;

@Component("kassiopeiaAgent")
public class KassiopeiaAgent {

    private static final Logger logger = Logger.getLogger(KassiopeiaAgent.class);

    @Autowired
    private AbstractApplicationContext ctx;

    @Autowired
    private SEDA seda;

    @Value("${io.ping.enable}")
    private boolean pingEnabled;

    @Autowired
    private Alerting alerting;

    @Autowired
    private AgentStatusHolder statusHolder;

    @PostConstruct
    public void init() {
        logger.info("Agent ID: " + AgentIDHolder.getThisAgentId());
        if (!pingEnabled) {
            logger.warn("Ping is DISABLED");
        }
        alerting.alertAgentStarted();
    }

    public void start(final TaskDescriptor task) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    logger.info("Starting task...");
                    seda.start(task);
                } catch (SedaException se) {
                    logger.error(se, se);
                    alerting.alertSedaError(se);
                }
            }
        },"Task-Starter").start();

        statusHolder.setStatus(AgentStatus.TASK);
        statusHolder.setTaskSummary(new TaskSummary(task.getName(), task.getDescription()));
    }

    public void stop() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    logger.info("Stopping task...");
                    seda.stop();
                } catch (SedaException se) {
                    logger.error(se, se);
                    alerting.alertSedaError(se);
                }
            }
        }).start();

        statusHolder.setStatus(AgentStatus.IDLE);
        statusHolder.setTaskSummary(null);
    }

    public void shutdown() {
        logger.info("Shutting down Kassiopeia");
        ctx.close();
    }

    public String getAgentId() {
        return AgentIDHolder.getThisAgentId();
    }

    public boolean isPingEnabled() {
        return pingEnabled;
    }
}
